package org.fixies.spreadsheet;

import org.fixies.spreadsheet.converter.DataSetConverter;
import org.fixies.utils.LineSeparator;
import org.fixies.utils.Validator;

import java.util.*;

/**
 * データセット
 *
 * @author Kawasaki
 */
public class Unit implements Iterable<Row>, Element {

    private final String origin_;

    private final List<Row> rows_;

    private final MetaData metaData_;

    /**
     * コンストラクタ
     *
     * @param origin   起源
     * @param metadata メタデータ
     * @param rows     行
     */
    public Unit(String origin, Map<String, String> metadata,
                       List<List<String>> rows) {

        origin_ = origin;
        metaData_ = new MetaData(metadata);
        Validator.notNull(rows);
        rows_ = Collections.unmodifiableList(convert(rows));

    }

    private List<Row> convert(List<List<String>> data) {
        List<Row> rows = new ArrayList<Row>(data.size());
        for (int i = 0; i < data.size(); i++) {
            List<String> rowData = data.get(i);
            Row row = new Row(rowData, this, i);
            rows.add(row);
        }
        return rows;
    }

    public String getId() {
        return metaData_.getRequiredMetaData("ID");
    }

    public Iterator<Row> iterator() {
        return rows_.iterator();
    }

    public int size() {
        return rows_.size();
    }

    public String getMetaData(String key) {
        return metaData_.getMetaData(key);
    }

    public String getRequiredMetaData(String key) {
        return metaData_.getRequiredMetaData(key);
    }

    public String[][] toStringArray() {
        String[][] array = new String[size()][];
        for (int i = 0; i < size(); i++) {
            array[i] = rows_.get(i).toStringArray();
        }
        return array;
    }

    @Override
    public String toString() {
        return metaData_.toString()
                + LineSeparator.SYSTEM_DEFAULT
                + rows_.toString();
    }

    public String getOrigin() {
        return origin_ + ", unit=[" + getId() + "]";
    }

    public <T> T convert(DataSetConverter<T> converter) {
        converter.setDataSet(this);
        return converter.convert();
    }

    public boolean contains(String key) {
        return metaData_.contains(key);
    }

    public Set<String> getMetaDataKeys() {
        return metaData_.getMetaDataKeys();
    }
}